#pragma once

#ifndef T_TASK_POOL_H
#define T_TASK_POOL_H

#include <QObject>
#include <QSemaphore>
#include <functional>
#include <list>

#include "TTaskClosureSet.h"
#include "TTaskClosure.h"
#include "TTimer.h"

class TThreadPool;

/*
 * 要点：bind的值应该传值的，或者是智能指针有效的
 * 同步gui，应该判定当前不属于一个线程，否则同步线程无效，如果有效，那么应该在内部等待调用完毕，接口返回
 * 重载函数绑定需要写清函数类型
 * 编程模型：异步任务，到多线程中执行，执行完毕后，把数据携带到gui进行使用
 * emplace_back对比push_back更加快，是右值引用的
*/

/* std::bind */
typedef std::function<void()> TTask;

class TTaskQueue :public QObject
{
    Q_OBJECT
private:
    TTaskQueue();
    ~TTaskQueue();

public:
    static TTaskQueue &get() {
        static TTaskQueue _instance;
        return _instance;
    }

    bool queueGuiTask(TTask const& task,bool sync = false);
    bool queueBackgroundTask(TTask const& task);
    TTimer* queueTimerTask(TTask const& task,size_t delay,bool repeat = false);/* 重复计数器会慢慢形成误差 */

    TTaskClosureSet<void*>	g_task_closure_map;
    std::list<TTimer*> g_timer_map;
private:
    bool eventFilter(QObject *obj, QEvent *event) override;

    std::mutex m_timerMutex;
    std::shared_ptr<TThreadPool> m_threadPool;
};

#endif
